#pragma once

#include <windows.h>
#include <algorithm>
#include <vector>
#include "MacroDefs.h"


enum ANIMATION_MODE
{
	AM_PLAY = 1,
	AM_REVERSE,
	AM_FWBOUNCE,
	AM_BWBOUNCE,
};


class AnimationPhase
{
	private:
		float	_elapsed;
		bool	_isDone;
		int		_frameCount;

	public:
		AnimationPhase()
		{
			_elapsed = 0;
			_isDone = false;
			_frameCount = 0;

			loop = false;
			framesPerSec = 30;
			startFrame = 0;
			endFrame = 0;
			animationMode = AM_PLAY;
			frameWidth = 0;
			frameHeight = 0;
			currentFrame = 0;
			startPosX = 0;
			startPosY = 0;
		}


		AnimationPhase(int fps, int w, int h, int start, int end, int startx = 0, int starty = 0, bool looped = false, ANIMATION_MODE mode = AM_PLAY)
		{
			_elapsed = 0;
			_isDone = false;
			_frameCount = (end - start);

			loop = looped;
			framesPerSec = fps;
			frameWidth = w;
			frameHeight = h;
			startFrame = start;
			endFrame = end - 1;
			animationMode = mode;
			startPosX = startx;
			startPosY = starty;
			
			switch(animationMode)
			{
			case AM_PLAY:
			case AM_FWBOUNCE:
			default:
				currentFrame = startFrame;
				break;
			case AM_REVERSE:
			case AM_BWBOUNCE:
				currentFrame = endFrame;
				break;
			}
		}

		friend class IAnimator;

		bool loop;
		int framesPerSec;
		int startFrame;
		int endFrame;
		int frameWidth;
		int frameHeight;
		int currentFrame;
		int	startPosX;
		int startPosY;

		ANIMATION_MODE animationMode;
};


class IAnimator
{
	private:

		int		_frameWidth;
		int		_frameHeight;

		int		_currentAnim;

		std::vector<AnimationPhase*>	_animations;


	protected:
		int		_srcWidth;
		int		_srcHeight;


		void AdvanceAnimation(float time, RECT* r);

	public:
		IAnimator(): _currentAnim(-1), _frameWidth(0), _frameHeight(0), _srcWidth(0), _srcHeight(0)
		{

		}
		

		~IAnimator() 
		{
			std::vector<AnimationPhase*>::iterator iter;

			for(iter = _animations.begin(); iter != _animations.end(); ++iter)
			{
				AnimationPhase* ap = (*iter);
				SAFE_DELETE(ap);
			}

			_animations.clear();
		}


		int AddAnimationPhase(AnimationPhase* phase)
		{
			_animations.push_back(phase);
			int id = (std::find(_animations.begin(), _animations.end(), phase) - _animations.begin());

			if((int)_animations.size() == 1)
			{
				RECT r;
				this->AdvanceAnimation(0.0f, &r);
			}

			return (_currentAnim = id);
		}


		void SetCurrentAnimation(int index) 
		{ 
			if(index >= 0 &&
				index < (int)_animations.size())
			{
				_currentAnim = index;
			}
		}


		void Play();
		void Pause();
		void Stop();
		void Restart() const {}
		void SkipToFrame(int frame) const {}
		void Begin();
		void End();

		bool IsStopped();
		bool IsPlaying();
		bool IsPaused();
};
